package com.zzyy.dtx.pay.service;

import com.alibaba.fastjson2.JSON;
import com.zzyy.dtx.commons.enums.MsgEnum;
import com.zzyy.dtx.commons.utils.DatetimeUtil;
import com.zzyy.dtx.msg.api.MsgApi;
import com.zzyy.dtx.msg.dto.MsgDTO;
import com.zzyy.dtx.order.api.OrderApi;
import com.zzyy.dtx.order.dto.OrderDTO;
import com.zzyy.dtx.pay.dto.PayDTO;
import com.zzyy.dtx.pay.entities.Pay;
import com.zzyy.dtx.pay.mapper.PayMapper;
import com.zzyy.dtx.score.dto.ScoreDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Random;

/**
 * @auther zzyy
 * @create 2023-04-16 16:29
 */
@Service
public class PayService {

    @Resource
    private PayMapper payMapper;

    public Pay findPayByOrderNo(String orderNo)
    {
        Pay pay = new Pay();
        pay.setOrderNo(orderNo);

        pay = this.payMapper.selectOne(pay);

        return pay;
    }

    @Transactional
    public String createPay(PayDTO payDTO)
    {
        Pay pay = new Pay();
        BeanUtils.copyProperties(payDTO,pay);
        //交易流水号
        Random random = new Random();
        //随机 1000-9999的数字
        int n = random.nextInt(8999)+1000;
        String payno = DatetimeUtil.getCurrentDatetime()+ n;
        pay.setPayNo("pay-"+payno);
        pay.setStatus((byte)0);
        this.payMapper.insertSelective(pay);
        return pay.getPayNo();
    }

    //通过支付流水号，找出支付订单的信息
    public Pay findPayByPayNo(String payNo)
    {
        Pay pay = new Pay();
        pay.setPayNo(payNo);

        pay = this.payMapper.selectOne(pay);

        return pay;
    }

    //==========================2023.5.21 V1 第一版==========================
    /*public  void confirmPayHandle(String payNo){
        System.out.println("======进入PayService里面的confirmPayHandle方法 V1");

        Pay pay = new Pay();
        pay.setPayNo(payNo);
        pay = this.payMapper.selectOne(pay);
        //执行本地事务提交，对应设计图步骤3，只是only完成了支付微服务的本地业务，后续再补充。
        this.confirmPay(pay);
    }

    @Transactional
    public void confirmPay(Pay pay)
    {
        //设置支付状态：'支付状态 -1：取消 0 未完成 1已完成 -2:异常',
        pay.setStatus((byte)1);
        this.payMapper.updateByPrimaryKeySelective(pay);
    }*/

    //==========================2023.5.21 V2 第2版==========================
   /* @Resource
    private MsgApi msgApi;
    @Value("${spring.application.name}")
    private String appName;
    private static final String MQ_ORDER_ROUTING_KEY = "order.routing.key";

    public  void confirmPayHandle(String payNo){
        System.out.println("======进入PayService里面的confirmPayHandle方法 V2");

        Pay pay = new Pay();
        pay.setPayNo(payNo);
        //payConfirmForm.html页面上点击【模拟支付】
        pay = this.payMapper.selectOne(pay);

        //发送“待发送”的订单消息给我msg5001微服务，对应设计图步骤1
        this.sendOrderPrepareMsg(pay);
        //执行本地事务提交，对应设计图步骤3，只是only完成了支付微服务的本地业务，后续再补充。
        this.confirmPay(pay);
        //通知消息可以发送了，对应设计图步骤4
        this.sendOrderConfirmMsg(pay.getOrderNo());
    }

    private void sendOrderPrepareMsg(Pay pay)
    {
        MsgDTO msgDTO = new MsgDTO();
        String msgid= MsgEnum.ORDER.getCode()+"-"+pay.getOrderNo();
        msgDTO.setMsgId(msgid);
        msgDTO.setAppName(this.appName);
        msgDTO.setRoutingKey(MQ_ORDER_ROUTING_KEY);

        OrderDTO orderDTO=new OrderDTO();
        orderDTO.setUserId(pay.getUserId());
        orderDTO.setOrderNo(pay.getOrderNo());
        msgDTO.setJsonMsg(JSON.toJSONString(orderDTO));

        this.msgApi.prepareMsg(msgDTO);

    }

    @Transactional
    public void confirmPay(Pay pay)
    {
        //设置支付状态：'支付状态 -1：取消 0 未完成 1已完成 -2:异常',
        pay.setStatus((byte)1);
        this.payMapper.updateByPrimaryKeySelective(pay);
    }

    private void sendOrderConfirmMsg(String orderNo)
    {
        MsgDTO msgDTO = new MsgDTO();

        String msgid = MsgEnum.ORDER.getCode()+"-"+ orderNo;
        msgDTO.setMsgId(msgid);

        this.msgApi.confirmMsg(msgDTO);
    }*/

    //==========================2023.5.28 V3 第3版==========================
    @Resource private MsgApi msgApi;
    @Resource private OrderApi orderApi;

    @Value("${spring.application.name}")
    private String appName;

    private static final String MQ_ORDER_ROUTING_KEY = "order.routing.key";
    private static final String MQ_SCORE_ROUTING_KEY = "score.routing.key";

    public  void confirmPayHandle(String payNo){
        System.out.println("======进入PayService里面的confirmPayHandle方法 V3");

        Pay pay = new Pay();
        pay.setPayNo(payNo);
        //payConfirmForm.html页面上点击【模拟支付】
        pay = this.payMapper.selectOne(pay);

        //发送“待发送”的订单消息给我msg5001微服务，对应设计图步骤1
        this.sendOrderPrepareMsg(pay);
        //发送"待发送"的积分消息给我msg5001微服务，对应设计图的步骤1
        OrderDTO orderDTO=this.orderApi.findOrderNo(pay.getOrderNo());
        this.sendScorePrepareMsg(pay,orderDTO.getLargessScore());

        //执行本地事务提交，对应设计图步骤3
        this.confirmPay(pay);

        //int age = 10/0;


        //通知消息可以发送了，对应设计图步骤4
        this.sendOrderConfirmMsg(pay.getOrderNo());
        //通知消息可以发送了，对应设计图的步骤4
        this.sendScoreConfirmMsg(pay.getOrderNo());
    }

    private void sendOrderPrepareMsg(Pay pay)
    {
        MsgDTO msgDTO = new MsgDTO();
        String msgid= MsgEnum.ORDER.getCode()+"-"+pay.getOrderNo();
        msgDTO.setMsgId(msgid);
        msgDTO.setAppName(this.appName);
        msgDTO.setRoutingKey(MQ_ORDER_ROUTING_KEY);

        OrderDTO orderDTO=new OrderDTO();
        orderDTO.setUserId(pay.getUserId());
        orderDTO.setOrderNo(pay.getOrderNo());
        msgDTO.setJsonMsg(JSON.toJSONString(orderDTO));

        this.msgApi.prepareMsg(msgDTO);

    }
    private void sendScorePrepareMsg(Pay obj,int score){
        MsgDTO msgDTO=new MsgDTO();
        String msgid= MsgEnum.SCORE.getCode()+"-"+obj.getOrderNo();
        msgDTO.setMsgId(msgid);
        msgDTO.setAppName(this.appName);
        msgDTO.setRoutingKey(MQ_SCORE_ROUTING_KEY);
        ScoreDTO scoreDTO=new ScoreDTO();
        scoreDTO.setUserId(obj.getUserId());
        scoreDTO.setOrderNo(obj.getOrderNo());
        scoreDTO.setScore(score);
        msgDTO.setJsonMsg(JSON.toJSONString(scoreDTO));
        this.msgApi.prepareMsg(msgDTO);
    }

    @Transactional
    public void confirmPay(Pay pay)
    {
        //设置支付状态：'支付状态 -1：取消 0 未完成 1已完成 -2:异常',
        pay.setStatus((byte)1);
        this.payMapper.updateByPrimaryKeySelective(pay);
    }

    private void sendOrderConfirmMsg(String orderNo)
    {
        MsgDTO msgDTO = new MsgDTO();
        String msgid = MsgEnum.ORDER.getCode()+"-"+ orderNo;
        msgDTO.setMsgId(msgid);
        this.msgApi.confirmMsg(msgDTO);
    }

    private void sendScoreConfirmMsg(String orderNo){
        MsgDTO msgDTO=new MsgDTO();
        String msgid=MsgEnum.SCORE.getCode()+"-"+orderNo;
        msgDTO.setMsgId(msgid);
        this.msgApi.confirmMsg(msgDTO);
    }
}

